package cn.com.utt.unms.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.com.utt.common.log.doLog;
import cn.com.utt.common.mapper.UserMapper;
import cn.com.utt.common.util.LocaleMessageSourceUtil;
import cn.com.utt.common.util.Tips;
import cn.com.utt.common.vo.RestResult;
import cn.com.utt.common.vo.User;
import cn.com.utt.unms.mapper.DeviceMapper;
import cn.com.utt.unms.mapper.GroupMapper;
import cn.com.utt.unms.mapper.NetworkMapper;
import cn.com.utt.unms.mapper.GroupNetworkMapper;
import cn.com.utt.unms.pojo.Group;
import cn.com.utt.unms.pojo.Network;
import cn.com.utt.unms.service.GroupService;
import cn.com.utt.unms.vo.GroupToNetwork;

@Service("groupService")
public class GroupServiceImpl implements GroupService {
	
	@Autowired
    private LocaleMessageSourceUtil messageSourceUtil;

	@Autowired
	private GroupMapper groupMapper;
	
	@Autowired
	private UserMapper userMapper;

	@Autowired
	private DeviceMapper deviceMapper;

	@Autowired
	private NetworkMapper networkMapper;

	@Autowired
	private GroupNetworkMapper groupNetworkMapper;
	
	@Override
	@Transactional
	@doLog(description = Tips.LogAddGroup, key = { "#group.name" })
	public RestResult add(Group group) {
		RestResult result=new RestResult();
		groupMapper.save(group);
		return result;
	}

	@Override
	@Transactional
	@doLog(description = Tips.LogUpdateGroup, key = { "#group.name" })
	public RestResult update(Group group) {
		RestResult result=new RestResult();
		groupMapper.update(group);
		List<Long> networkIds = new ArrayList<>();
		List<Network> networks = networkMapper.queryByGroupId(group.getId());
		for (Network network : networks) {
			networkIds.add(network.getId());
		}
		if(networkIds.size() > 0){
			networkMapper.updateGroup(networkIds, group.getName());
		}
		return result;
	}

	@Override
	@Transactional
	@doLog(description = Tips.LogDeleteGroup, key = { "" })
	public RestResult delete(long groupId) {
		RestResult result = new RestResult();
		List<Long> networkIds = groupNetworkMapper.queryByGroupId(groupId);
		if (networkIds.size() > 0) {
			int count = deviceMapper.queryIfHasReference(networkIds);
			if (count > 0) {
				result.setErrorCode(1);
				result.setErrorMsg(messageSourceUtil.getMessage(Tips.GroupNoDelete1));
				return result;
			}
		}
		
		List<User> users = userMapper.queryByGroupId(groupId);
		if(!users.isEmpty()){
			result.setErrorCode(1);
			result.setErrorMsg(messageSourceUtil.getMessage(Tips.GroupNoDelete2));
			return result;
		}
		
		List<Long> ids = new ArrayList<Long>();
		List<Group> groups = queryChildrenGroup(groupId,groupId);
		if (groups != null) {
			for (Group group : groups) {
				ids.add(group.getId());
			}
		}
		
		if (!networkIds.isEmpty()) { // 局点组下有局点
			networkMapper.delete(networkIds);
			groupMapper.delete(ids);
			groupNetworkMapper.deleteByNetworkIds(networkIds);
			result.setErrorMsg(messageSourceUtil.getMessage(Tips.OperationSucceed));
		} else {
			groupMapper.delete(ids);
			result.setErrorMsg(messageSourceUtil.getMessage(Tips.OperationSucceed));
		}

		return result;
	}

	@Override
	public List<Group> queryGroupsTree(long groupId, Boolean net,Long childrenId) {
		long id;
		if(childrenId != null && childrenId != 0){
			User children = userMapper.queryById(childrenId);
			User parent = userMapper.queryById(children.getParentId());
			id = parent.getGroupId();
		}else{
			id = groupId;
		}
		
		if(net != null && !net){
			List<Group> tree = queryChildrenGroup(id,id);
			return tree;
		}else{
			List<Group> tree = new ArrayList<>();
			List<GroupToNetwork> gTns = queryGroupToNetwork(id, id);
			for (GroupToNetwork groupToNetwork : gTns) {
				Group group = new Group();
				Group temp = new Group();
				if(groupToNetwork.getnId() != null){
					temp.setId(-groupToNetwork.getnId());
					temp.setName(groupToNetwork.getnName());
					temp.setpId(groupToNetwork.getnPid());
					temp.setType((byte) 1);
					tree.add(temp);
					group.setHasNetwork((byte)1);
				}
				
				group.setId(groupToNetwork.getgId());
				if(tree.contains(group)){
					continue;
				}
				group.setName(groupToNetwork.getgName());
				group.setpId(groupToNetwork.getgPid());
				if(!tree.contains(group)){
					tree.add(group);
				}
			}
			return tree;
		}
		
	}
	
	private List<GroupToNetwork> queryGroupToNetwork(long groupId,long userGroupId) {
		
		List<GroupToNetwork> result = new ArrayList<>();
		
		if(groupId == userGroupId){
			List<GroupToNetwork> groupToNetwork = groupMapper.queryByIdContainsNetwork(groupId);
			result.addAll(groupToNetwork);
		}
		
		List<GroupToNetwork> groupToNetworks = groupMapper.queryByPidContainsNetwork(groupId);
		if (groupToNetworks == null || groupToNetworks.isEmpty()) {
			return result;
		} else {
			
			Set<Long> ids = groupToNetworks.stream().map(GroupToNetwork::getgId).collect(Collectors.toSet());
			for (Long id : ids) {
				List<GroupToNetwork> childrens = queryGroupToNetwork(id,userGroupId);
				if (childrens != null) {
					result.addAll(childrens);
				}
			}
		}
		result.addAll(groupToNetworks);
		return result;
	}

	// 查找组所有子组
	@Override
	public List<Group> queryChildrenGroup(long groupId,long userGroupId) {
		
		List<Group> result = new ArrayList<>();
		
		if(groupId == userGroupId){
			Group root = groupMapper.queryById(groupId);
			root.setpId(0L);
			result.add(root);
		}
		
		List<Group> groups = groupMapper.queryByPid(groupId);
		if (groups == null || groups.isEmpty()) {
			return result;
		} else {
			for (Group group : groups) {
				List<Group> childrens = queryChildrenGroup(group.getId(),userGroupId);
				if (childrens != null) {
					result.addAll(childrens);
				}
			}
		}
		result.addAll(groups);
		return result;
	}

	// 查找所有直系父分组
	@Override
	public List<Long> queryDirectGroup(long groupId) {
		List<Long> result = new ArrayList<>();
		result.add(groupId);
		Group group = groupMapper.queryById(groupId);
		if (group == null) {
			return null;
		} else {
			if (group.getpId() != null) {
				List<Long> directs = queryDirectGroup(group.getpId());
				if (directs != null) {
					result.addAll(directs);
				}
			}
		}
		return result;
	}

	@Override
	public boolean hasRight(long userGroupId, long groupId) {

		if (userGroupId == groupId) {
			return true;
		}
		List<Group> groups = queryChildrenGroup(userGroupId,userGroupId);
		if (groups != null) {
			for (Group group : groups) {
				if (groupId == group.getId()) {
					return true;
				}
			}
		}
		return false;
	}

	// 查找组的根节点
	@Override
	public long queryRootGroup(long groupId) {
		Group group = groupMapper.queryById(groupId);
		if (group.getpId() == 0) {
			return group.getId();
		} else {
			return queryRootGroup(group.getpId());
		}
	}

}
